package main

import (
	"bytes"
	"fmt"
	"io"
	"strings"
)

type Header struct {
	Key, Value string
}

type Status struct {
	Code   int
	Reason string
}

func WriteResponse(w io.Writer, st Status, headers []Header, body io.Reader) error {
	//设置协议
	_, err := fmt.Fprintf(w, "Http/1.1 %d %s\r\n", st.Code, st.Reason)
	if err != nil {
		return err
	}

	//设置头信息
	for _, h := range headers {
		_, err := fmt.Fprintf(w, "%s: %s\r\n", h.Key, h.Value)
		if err != nil {
			return err
		}
	}

	//设置换行
	if _, err := fmt.Fprintf(w, "\r\n"); err != nil {
		return err
	}

	//设置body提
	n, err := io.Copy(w, body)
	fmt.Println("write", n)
	return err
}

//简化版，这么定义的原因是，Fprintf源码中，需要实现io.Write方法别切返回长度和错误
//本地化重写该方法
type errWriter struct {
	Writer io.Writer
	err    error
}

func (e *errWriter) Write(buf []byte) (int, error) {
	if e.err != nil {
		return 0, e.err
	}
	var n int
	n, e.err = e.Writer.Write(buf)
	return n, e.err
}

func WriteResponse2(w io.Writer, st Status, headers []Header, body io.Reader) error {
	ew := &errWriter{Writer: w}
	fmt.Fprintf(ew, "Http/1.1 %d %s\r\n", st.Code, st.Reason)

	//设置头信息
	for _, h := range headers {
		fmt.Fprintf(ew, "%s: %s\r\n", h.Key, h.Value)
	}

	//设置换行
	fmt.Fprintf(w, "\r\n")

	//设置body提
	io.Copy(ew, body)
	return ew.err

}

func main() {
	st := Status{
		200,
		"success",
	}

	headers := []Header{
		{
			"METHOD",
			"POST",
		},
		{
			"server",
			"openresty",
		},
	}

	body := "hello world"

	resp := ""

	err := WriteResponse(bytes.NewBufferString(resp), st, headers, strings.NewReader(body))
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("end")
}
